package com.yonyou.hxjy.job;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.yonyou.hxjy.controller.SM2Example;
import com.yonyou.hxjy.dao.JobLogDao;
import com.yonyou.hxjy.model.JobLogModel;
import com.yonyou.hxjy.service.bm.BmYonsuiteService;
import com.yonyou.hxjy.utils.BuildToken;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.DateUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * @ClassName YsProductToRedisJob
 * @Description YS物料档案信息同步Redis
 * @Author HuangWb
 * @Date 2023/9/6 18:35
 * @Version 1.0
 */
@Component
@RestController
public class ysJsToBmJob {

    private static final Logger logger = LoggerFactory.getLogger(ysJsToBmJob.class);

    @Autowired
    public BmYonsuiteService bmYonsuiteService;
    @Value("${bodyEncryptionKey}")
    private String bodyEncryptionKey;
    @Value("${signEncryptionPrivateKey}")
    private String signEncryptionPrivateKey;
    @Value("${bodyDecryptionKey}")
    private String bodyDecryptionKey;
    @Value("${TARGET_URL}")
    private String TARGET_URL;
    @Value("${APP_ID}")
    private String APP_ID;
    @Value("${app_secret}")
    private String app_secret;
    @Value("${grant_type}")
    private String grant_type;

    @Value("${ys.config.tenantId}")
    private String tenantId;

    @Resource
    public JobLogDao jobLogDao;


    /**
     * @return
     * @Author Huangwb
     * @Description YS查询银行支付信息  回传结算单状态
     * @Date 14:28 2023/9/6
     * @Param
     **/
    @XxlJob("jshc")
    @GetMapping("/getJob")
    public ReturnT<String> ysJsToBmJob(String param) throws Exception {


        int pageIndex = 1;
        int maxRetries = 3;
        List<Integer> statementdetailstatus = new ArrayList<>();
        statementdetailstatus.add(2);

        System.out.println("statementdetailstatus"+statementdetailstatus);


            try {
                HashMap<String, Object> params = new HashMap<>();
                params.put("pageIndex", pageIndex);
                params.put("pageSize", 100);
                params.put("receipttype", 2);
                params.put("settlemode_code", "system_0001");
                params.put("statementdetailstatus", statementdetailstatus);
                params.put("statementstatus", 4);
                params.put("isSum", false);
                // 业务逻辑
                JSONObject settlebench = bmYonsuiteService.settlebench(params);
                JSONArray jsonArray = settlebench.getJSONObject("data").getJSONArray("recordList");
                if (jsonArray.size() == 0) {
                    InsertLogger(DateUtils.formatDate(new Date()), "0", "没有查询到对应的结算单数据");
                    logger.error("没有查询到对应的结算单数据");
                    return ReturnT.FAIL;

                }
                if (!"200".equals(settlebench.getStr("code"))) {
                    String errorMsg = "结算工作台列表查询失败: " + settlebench.getStr("message");
                    InsertLogger(DateUtils.formatDate(new Date()), "0", "没有查询到对应的结算单数据");
                    logger.error(errorMsg);
                    return ReturnT.FAIL;
                   // throw new Exception(errorMsg);
                }
                Integer endPageIndex = settlebench.getJSONObject("data").getInt("endPageIndex");
                if (endPageIndex > 1) {
                    for (int s = 2; s <= endPageIndex; s++) {
                        params.put("pageIndex", pageIndex);
                        params.put("pageSize", 100);
                        params.put("receipttype", 2);
                        params.put("settlemode_code", "system_0001");
                        params.put("statementdetailstatus", statementdetailstatus);
                        params.put("isSum", false);
                        JSONObject settlebenchxh = bmYonsuiteService.settlebench(params);
                        if (!"200".equals(settlebenchxh.getStr("code"))) {
                            String errorMsg = "结算工作台列表查询失败: " + settlebench.getStr("message");
                            logger.error(errorMsg);
                            return ReturnT.FAIL;
                            // throw new Exception(errorMsg);
                        }
                        jsonArray.add(settlebenchxh.getJSONObject("data").getJSONArray("recordList"));
                        // 这里写你的循环体代码
                    }
                }

                for (int j = 0; j < jsonArray.size(); j++) {
                    // 获取当前索引处的JSONObject settleDetailId
                    JSONObject jsonObject = jsonArray.getJSONObject(j);

                    // 获取detailid   明细行id
                    String detailid = jsonObject.getStr("detailid");
                    String settleDetailId = jsonObject.getStr("settleDetailId");
                    //结算单编号
                    String detailcode = jsonObject.getStr("code");
                    logger.info("detailid"+detailid);

                    JSONObject dataJson = payDetail(settleDetailId);
                    logger.info("settleFeedback"+dataJson.toString());


                 if (!"0".equals(dataJson.getStr("code"))) {
                        InsertLogger(detailcode, "0", dataJson.getStr("msg"));
                        logger.error(dataJson.getStr("msg"));
                        return ReturnT.FAIL;
                       // throw new Exception(dataJson.getStr("msg"));
                    }
                    JSONArray dataArray = dataJson.getJSONArray("data");
                    if(dataArray.size()==0){
                        InsertLogger(detailcode, "0", "CBS没有对应数据，不回调");
                        logger.error(detailcode+"CBS没有对应数据，不回调");
                        continue;
                    }
                    //当status=4的时候，取payStatus=jhg的值，除了成功，其余判定为支付失败
                    String errorMsg = dataArray.getJSONObject(0).getStr("errorMsg");
                    String payStatus = dataArray.getJSONObject(0).getStr("payStatus");
                    String status = dataArray.getJSONObject(0).getStr("status");

                    HashMap<String, Object> settleFeedbackMap = new HashMap<>();
                    settleFeedbackMap.put("settleDetailAId", detailid);


                        if ("4".equals(status)||"3".equals(status)||"5".equals(status)||"6".equals(status)) {
                            int statusValue =4;
                            if("4".equals(status) && "g".equals(payStatus)){
                                statusValue=3;
                            }
                            if("4".equals(status) && (!"j".equals(payStatus)) && !"h".equals(payStatus) && !"g".equals(payStatus) ){
                                logger.info(detailcode+"status="+status+"payStatus"+payStatus+"不回写" );
                                continue;
                            }

                          //  int statusValue = "4".equals(status) ? ("g".equals(payStatus) ? 3 : 4) : 4;
                            settleFeedbackMap.put("statementdetailstatus", statusValue);

                            if (statusValue==4) {
                                settleFeedbackMap.put("settlefailreason", errorMsg);
                            }
                        JSONObject settleFeedback = bmYonsuiteService.settleFeedback(settleFeedbackMap);
                        logger.info("settleFeedback"+settleFeedback.toString());
                        if (!"200".equals(settleFeedback.getStr("code"))) {
                            String errorMsg1 = "结算工作台回调失败: " + settlebench.getStr("message");
                            logger.error(errorMsg1);
                            InsertLogger(detailcode, "0", errorMsg1);
                            return ReturnT.FAIL;
                        }else {
                            logger.info(settleDetailId+"回传成功");
                            InsertLogger(detailcode, "1", settleDetailId+"回传成功");
                        }
                    }


                }


            } catch (Exception e) {

                    logger.error("任务异常:", e.getMessage());
                    InsertLogger("", "0", e.getMessage());
                    return ReturnT.FAIL;


            }



        logger.info("租户：【{}】YS结算明细结果回传完成。", tenantId);
        return ReturnT.SUCCESS;
    }


    public JSONObject payDetail(String referenceNum) throws Exception {
        cn.hutool.json.JSONObject datajson = new cn.hutool.json.JSONObject();
        if (APP_ID == null || app_secret == null || grant_type == null) {
            throw new Exception("配置参数（APP_ID/app_secret/grant_type）不能为 null");
        }
        BuildToken selfBuildToken = new BuildToken();
        String token = selfBuildToken.getToken(APP_ID, app_secret, grant_type, TARGET_URL);
        if (token == null) {
            datajson.set("code", "999");
            datajson.set("msg", "toekn 生成失败为空");
            return datajson;
        }
        String uri = TARGET_URL + "/openapi/payment/openapi/v2/detail";
        CloseableHttpClient client = HttpClients.custom()
                // 禁止HttpClient自动解压缩
                .disableContentCompression()
                .build();


        JSONObject object = new JSONObject();
        object.set("referenceNum", referenceNum);

        HttpPost httpPost = SM2Example.setupRequest(JSONUtil.toJsonStr(object), signEncryptionPrivateKey, uri, bodyEncryptionKey, token);
        //System.out.println("httpPost"+httpPost);
        try (CloseableHttpResponse response = client.execute(httpPost)) {
            byte[] finalResponseData = SM2Example.handleResponse(response, bodyDecryptionKey);
            String finalResponseDataStr = new String(finalResponseData ,"utf-8");
            logger.info("\n返回结果：{}", finalResponseDataStr);

            datajson = JSONUtil.parseObj(finalResponseDataStr);
            return datajson;
        } catch (Exception ignored) {
            throw new Exception("网络连接失败或超时！");
        } finally {
            client.close();
        }

    }

    /**
     * @return
     * @Author Huangwb
     * @Description 插入数据库日志信息
     * @Date 14:30 2023/9/14
     * @Param
     **/
    private void InsertLogger(String code, String oneL, String mags) {  // 单据编号、是否成功、详细信息
        try {
            JobLogModel jobLogDTO = new JobLogModel();
            jobLogDTO.setJobClass("bm-ys"); // 执行器序号 -
            jobLogDTO.setJobCode(code);//单据编码
            jobLogDTO.setJobTime(new Date());
            jobLogDTO.setJobResult(oneL);//成功是0or1
            jobLogDTO.setJobResultMessage(mags);//成功是成功，失败是失败原因
            jobLogDTO.setJobLogUser("admin");//改成新华教育用户名称
            jobLogDao.insertJobLog(jobLogDTO);
        } catch (Exception e) {
            logger.error("插入日志错误：" + e.getMessage());
        }
    }





}
